parser grammar TPraserGramatica;

options {    
    language  = Java;
    output    = AST;
    //Esta es la referencia al Lexer
    tokenVocab = TLexerGramatica; 
}

tokens {

    //TOCKENS IMAGINARIOS SOLO PARA IMPRESION EN ARBOL
		START;
		LINEA;
		ASIGNACION;
		FUNCION;
		FUNCIONES;
		STATEMENT;
		EXPRESION;
		STATEMENT_IF;
		STATEMENT_ELSE;
		STATEMENT_FOR;
		STATEMENT_DO;
		STATEMENT_WHILE;
		EXP_BINARIA;
		INC_DEC;
		DO;
		WHILECOMPLEMENT;
		EXPR_INCR_DECR;
		VARIABLE;
		FUNCIONNUMERICA;
		NUM;
		EXPRESION_TERNARIA;
		VARIABLE;
		CADENA;		
		EXPRESION;
		EXP_ASIGNACION;
		EXP_CONDICIONAL;
		EXP_LOGICA_OR;
		EXP_LOGICA_AND;
		EXP_COMPARACION;
		EXP_ADICION;
		EXP_MULTIPLICACION;
		
}

@header { //parser

  package parser;
    
}


//LINEA DE ENTRADA AL LEXER
start: block
 ; 
 
block
 : (statement)* EOF
 ;
 


//DECLARACION DE OPERADORES
op_un_bool : LOGICAL_NOT | NOT_W ;
op_un_inc_dec : INC|DEC ;
op_un_aritm : PLUS|MINUS ;
op_bin_aritm : STAR|DIV|MOD|XOR ;
op_asignacion  : ASSIGN|MINUS_ASSIGN|PLUS_ASSIGN|STAR_ASSIGN|DIV_ASSIGN|MOD_ASSIGN ;
op_comparacion : LEQUAL|GREATER_THAN|LESS_THAN|GREATER_OR_EQUAL|LESS_OR_EQUAL|NOT_EQUAL|LESS_GREATER ;
op_condicional : AND_W | OR_W ;
op_bool_ternario: QUESTION;
op_asignacion_ternario: COLON ;


//NUMEROS
numero : op_un_aritm? DECIMAL_LITERAL
;

 
//OPERADORES VARIOS PARA EXPRESIONES ARITMETICAS
operador_unario :
    op_un_bool
    |op_un_aritm
    |op_un_inc_dec ;
operador_binario :
    op_bin_aritm
    |op_asignacion             
    |op_comparacion
    |op_condicional ;
var_aritm :
		var_numero
		|variable ;





//VARIABLE QUE CONTEMPLA CORCHETES [] CONTENIENDO DIGITOS O CARACTERES
array: IDENTIFIER   ;

var_array : numero|IDENTIFIER;
brack_var: var_array ((op_un_aritm|op_bin_aritm) var_array)?;

//VARIABLE QUE ADMITE UN PUNTO SEPARADOR PARA LA REPRESENTACION DE VARIABLES COMPLEJAS
variable: array (LBRACK brack_var RBRACK)? (DOT array)*;




//VARIABLES BOOLEANAS
var_bool :
TRUE |
FALSE |
funcionz;


//VARIABLES NUMERICAS
var_numero :
numero -> ^(NUM) 
|funcionx -> ^(FUNCIONNUMERICA)
|length -> ^(FUNCIONNUMERICA);
 


//EXPRESIONES ARITMETICAS BOOLEANAS O CONDICIONALES
expresion : assignment_expression* -> ^(EXPRESION);

assignment_expression : variable //conditional_expression 
  ( op_asignacion (conditional_expression|funciones))*   -> ^(EXP_ASIGNACION);


conditional_expression : logical_or_expression 
  (COLON logical_or_expression QUESTION logical_or_expression)?   -> ^(EXP_CONDICIONAL);

constant_expression : conditional_expression ;

logical_or_expression :  logical_and_expression 
  (OR_W  logical_and_expression )* -> ^(EXP_LOGICA_OR);

logical_and_expression : equality_expression 
  (AND_W equality_expression)*  -> ^(EXP_LOGICA_AND);

////EXPRESION UTILIZADA PARA COMPARACIONES
equality_expression :  additive_expression 
  (op_comparacion additive_expression )*  -> ^(EXP_COMPARACION)
  | LPAREN additive_expression
  op_comparacion additive_expression RPAREN  -> ^(EXP_COMPARACION);

//EXPRESION ARITMETICA
additive_expression : multiplicative_expression
  (op_un_aritm multiplicative_expression)*  -> ^(EXP_ADICION);

//EXPRESION ARITMETICA BINARIA
multiplicative_expression : unary_expression 
  (op_bin_aritm unary_expression)* -> ^(EXP_MULTIPLICACION);

bool_expresion: logical_and_expression|var_bool;

unary_expression 
  : 
  numero
  |STRING
  |variable
  | op_un_inc_dec variable
  | variable op_un_inc_dec
  | op_un_bool variable
  ;






//DEFINICION LINEAS DE CODIGO
stmt_block
    : LCURLY! statement* RCURLY!
    ;


//DEFINICION DE LA EXPRESION TERNARIA
exppresion_ternaria: 
  LPAREN expresion RPAREN op_bool_ternario (STRING|expresion) op_asignacion_ternario (STRING|expresion);

//TIPOS DE ARGUMENTOS QUE ADMITIRA UNA FUNCION
argumento: STRING|expresion;



 //FUNCIONES DISPONIBLES
 funciones: funcionx-> ^(FUNCTION_X)
 |funciony-> ^(FUNCTION_Y)
 |funcionz-> ^(FUNCTION_Z)
 |print-> ^(PRINT)
 |length-> ^(LENGTH)
 ;
 
 


//ESPECIFICACION DE FUNCIONES
funcionx: FUNCTION_X LPAREN argumento COMMA  argumento (COMMA argumento)? RPAREN;
funciony: FUNCTION_Y LPAREN argumento COMMA  argumento RPAREN;
funcionz: FUNCTION_Z LPAREN argumento COMMA argumento RPAREN;
print: PRINT LPAREN (PLUS? (variable|STRING))* RPAREN;
length: LENGTH LPAREN additive_expression RPAREN;
 
//STATEMENTS
//IF STATEMENT CON ELSE OPCIONAL  
 if_statement:
        IF LPAREN bool_expresion RPAREN statement else_statement?
       ;


else_statement:
           ELSE statement-> ^(STATEMENT_ELSE statement)
        ;


//DO STATEMENT CON WHILE OPCIONAL
do_statement: DO statement while_complem_statement -> ^(DO statement WHILECOMPLEMENT )
      ;

while_complem_statement:   WHILE LPAREN (bool_expresion) RPAREN FINALLINEA -> ^(WHILE LPAREN EXP_COMPARACION RPAREN FINALLINEA);


//WHILE STATEMENT
while_statement: WHILE LPAREN bool_expresion RPAREN statement 
    ;
    
    
//FOR STATEMENT
for_statement: FOR  LPAREN assignment_expression? FINALLINEA bool_expresion? FINALLINEA unary_expression? RPAREN  statement
              ;

//DEFINICION DE DIFERENTES POSIBLES STATEMENTS
statement: if_statement-> ^(STATEMENT_IF if_statement)
					|do_statement-> ^(STATEMENT_DO do_statement)
					|while_statement FINALLINEA?-> ^(STATEMENT_WHILE while_statement)
					|for_statement-> ^(STATEMENT_FOR for_statement)
					|expresion FINALLINEA
					|funciones
					|stmt_block
					;
